package br.com.pnfp.web.control.actions;

import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.actions.DispatchAction;
import org.springframework.beans.factory.annotation.Autowired;

import br.com.pnfp.web.control.exceptions.SessaoInvalidaException;
import br.com.pnfp.web.model.dao.ICidadeDAO;
import br.com.pnfp.web.model.dao.ICupomDAO;
import br.com.pnfp.web.model.dao.IDoadorDAO;
import br.com.pnfp.web.model.dao.IEmpresaDAO;
import br.com.pnfp.web.model.dao.IEntidadeDAO;
import br.com.pnfp.web.model.dao.ILocalidadeDAO;
import br.com.pnfp.web.model.dao.IRamoAtividadeDAO;
import br.com.pnfp.web.model.dao.ITipoLocalidadeDAO;
import br.com.pnfp.web.model.dao.IUsuarioDAO;
import br.com.pnfp.web.model.enums.TipoUsuario;
import br.com.pnfp.web.model.vo.Doador;
import br.com.pnfp.web.model.vo.Entidade;
import br.com.pnfp.web.model.vo.Usuario;

import com.google.gson.Gson;

public class DefaultAction extends DispatchAction {
	
	private static final SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
	private static final SimpleDateFormat sdfDojo = new SimpleDateFormat("yyyy-MM-dd");
	private static final SimpleDateFormat sdhf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
	private static final DecimalFormat df = new DecimalFormat("###,##0.00");
	
	@Autowired
	private ICidadeDAO cidadeDAO;
	@Autowired
	private IEntidadeDAO entidadeDAO;
	@Autowired
	private IDoadorDAO doadorDAO;
	@Autowired
	private IEmpresaDAO empresaDAO;
	@Autowired
	private ILocalidadeDAO localidadeDAO;
	@Autowired
	private IRamoAtividadeDAO ramoAtividadeDAO;
	@Autowired
	private ITipoLocalidadeDAO tipoLocalidadeDAO;
	@Autowired
	private IUsuarioDAO usuarioDAO;
	@Autowired
	private ICupomDAO cupomDAO;

	
	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		if(!mapping.getPath().equals("/login")) {
			if(request.getParameter("method") != null && request.getParameter("method").equals("iniciar") && request.getParameter("method").equals("login")) {
				if(request.getSession().getAttribute("usuario") == null) {
					request.getSession().invalidate();
					addMessage(request, "login.usuario.sessao.invalida");
					return mapping.findForward("index");
				}
			}
		}
		
		getMessages(request).clear();
		request.setAttribute("dataAtual", sdf.format(new Date()));
		
		Calendar amanha = Calendar.getInstance();
		amanha.setTime(new Date());
		request.setAttribute("dataAmanha", sdfDojo.format(amanha.getTime()));
		
		try {
			ActionForward action = super.execute(mapping, form, request, response);
			if(!mapping.getPath().equals("/login") && request.getParameter("ajax") == null) {
				initMenuValues(request);
			} else {
				if(!request.getParameter("method").equals("sair") && !request.getParameter("method").equals("iniciar") && getUsuario(request) != null && request.getParameter("ajax") == null) {
					initMenuValues(request);	
				}
			}
			
			return action;
		} catch(SessaoInvalidaException exc) {
			return mapping.findForward("sair"); 
		}
	}
	
	private void initMenuValues(HttpServletRequest request) {
		
		if(isAdministrator(request)) {
			//Consulta Qtde de Cupons para Envio
			Entidade vo = new Entidade();
			vo.setUsuarioSistema(getUsuario(request));
			List<Entidade> entidades = getEntidadeDAO().consultar(vo);
			
			for(Entidade entidade : entidades) {
				Integer qtdeCupom = getCupomDAO().consultaQtdeCupomParaEnvio(getUsuario(request), entidade.getCodigo());
				String value = "";
				if(qtdeCupom > 0) {
					entidade.setQtdeCupoms(qtdeCupom);				
				}	
			}
			request.setAttribute("qtdeCupomEnvioEntidades", entidades);
			
			List<Doador> doadores = getDoadorDAO().consultar(new Doador(getUsuario(request)));
			
			List<Doador> pendencias = new ArrayList<Doador>();
			for(Doador doador : doadores) {
				if(doador.getEntidade() == null)
					pendencias.add(doador);
			}
			if(pendencias.size() > 0)
				request.setAttribute("qtdeDoadorSemEntidade", pendencias.size());
			
			Integer qtdeCupomSemAssociacao = getCupomDAO().consultaQtdeCupomSemAssociacao(getUsuario(request));
			request.setAttribute("qtdeCupomSemAssociacao", qtdeCupomSemAssociacao);
		}		
	}
	
	protected void addMessage(HttpServletRequest request, String key, String... args) {
		ActionMessages messages = new ActionMessages();
		ActionMessage message = new ActionMessage(key, args);
		messages.add(ActionMessages.GLOBAL_MESSAGE, message);
		addMessages(request, messages);
	}
	
	protected void printJsonObjectToStream(Object vo, HttpServletResponse response) throws Exception {
		Gson gson = new Gson();
		String json = gson.toJson(vo);
		response.setContentType("application/json");
		PrintWriter out = response.getWriter();
		//out.println(json);
		out.println(new String(json.getBytes("UTF-8"), "ISO-8859-1"));
	}
	
	protected void printMessage(String message, HttpServletResponse response) throws Exception {
		response.setStatus(450);
		response.setContentType("text/text");
		PrintWriter out = response.getWriter();
		out.println(message);
	}	
		
	public Usuario getUsuario(HttpServletRequest request) {
		return (Usuario)request.getSession().getAttribute("usuario");
	}
	public void setUsuario(HttpServletRequest request, Usuario vo) {
		request.getSession().setAttribute("usuario", vo);
	}
	public Boolean isAdministrator(HttpServletRequest request) {
		return !getUsuario(request).getTipo().equals(TipoUsuario.DIGITADOR);
	}
	
	protected String gerarSenhaRandomica(){
		char[] chart ={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','@','!','?','#','$','%'};
		int len = 10;
		char[] senha= new char[len];
		int chartLenght = chart.length;
		Random rdm = new Random();
		for (int x=0; x<len; x++)
			senha[x] = chart[rdm.nextInt(chartLenght)];

		return new String(senha);
	}
	
	public SimpleDateFormat getDateFormat() {
		return sdf;
	}
	
	public SimpleDateFormat getDateHourFormat() {
		return sdhf;
	}
	
	public DecimalFormat getDecimalFormat() {
		return df;
	}
	
	public SimpleDateFormat getDateFormatDojo() {
		return sdfDojo;
	}
	
	public IRamoAtividadeDAO getRamoAtividadeDAO() {
		return ramoAtividadeDAO;
	}
	public void setRamoAtividadeDAO(IRamoAtividadeDAO ramoAtividadeDAO) {
		this.ramoAtividadeDAO = ramoAtividadeDAO;
	}
	public IEmpresaDAO getEmpresaDAO() {
		return empresaDAO;
	}
	public void setEmpresaDAO(IEmpresaDAO empresaDAO) {
		this.empresaDAO = empresaDAO;
	}
	public ITipoLocalidadeDAO getTipoLocalidadeDAO() {
		return tipoLocalidadeDAO;
	}
	public void setTipoLocalidadeDAO(ITipoLocalidadeDAO tipoLocalidadeDAO) {
		this.tipoLocalidadeDAO = tipoLocalidadeDAO;
	}
	public IUsuarioDAO getUsuarioDAO() {
		return usuarioDAO;
	}
	public void setUsuarioDAO(IUsuarioDAO usuarioDAO) {
		this.usuarioDAO = usuarioDAO;
	}
	public ICidadeDAO getCidadeDAO() {
		return cidadeDAO;
	}
	public void setCidadeDAO(ICidadeDAO cidadeDAO) {
		this.cidadeDAO = cidadeDAO;
	}
	public ILocalidadeDAO getLocalidadeDAO() {
		return localidadeDAO;
	}
	public void setLocalidadeDAO(ILocalidadeDAO localidadeDAO) {
		this.localidadeDAO = localidadeDAO;
	}
	public IDoadorDAO getDoadorDAO() {
		return doadorDAO;
	}
	public void setDoadorDAO(IDoadorDAO doadorDAO) {
		this.doadorDAO = doadorDAO;
	}
	public IEntidadeDAO getEntidadeDAO() {
		return entidadeDAO;
	}
	public void setEntidadeDAO(IEntidadeDAO entidadeDAO) {
		this.entidadeDAO = entidadeDAO;
	}
	public ICupomDAO getCupomDAO() {
		return cupomDAO;
	}
	public void setCupomDAO(ICupomDAO cupomDAO) {
		this.cupomDAO = cupomDAO;
	}

}
